﻿using EnvDTE;
using EnvDTE80;
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace UTGenerator
{
    class Compilador
    {
        public void Gerar(Type tipo, DTE2 aplicacao)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters cp = new CompilerParameters();
            Globals globais = aplicacao.Globals;

            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("mscorlib.dll");
            cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");

            Assembly asmDebuggerVisualizers = Assembly.LoadFile(globais["MicrosoftVisualStudioDebuggerVisualizersdll"].ToString());
            cp.ReferencedAssemblies.Add(asmDebuggerVisualizers.Location);

            Assembly asmEnvDte = Assembly.LoadFile(globais["envdtedll"].ToString());
            cp.ReferencedAssemblies.Add(asmEnvDte.Location);

            Assembly asmEnvDte80 = Assembly.LoadFile(globais["envdte80dll"].ToString());
            cp.ReferencedAssemblies.Add(asmEnvDte80.Location);

            Assembly asmEnvDte90 = Assembly.LoadFile(globais["envdte90dll"].ToString());
            cp.ReferencedAssemblies.Add(asmEnvDte90.Location);

            Assembly asmEnvDte100 = Assembly.LoadFile(globais["envdte100dll"].ToString());
            cp.ReferencedAssemblies.Add(asmEnvDte100.Location);

            Assembly asmXml = Assembly.LoadFile(globais["SystemXmldll"].ToString());
            cp.ReferencedAssemblies.Add(asmXml.Location);

            Assembly asmVSLangProj = Assembly.LoadFile(globais["VSLangProjdll"].ToString());
            cp.ReferencedAssemblies.Add(asmVSLangProj.Location);

            cp.ReferencedAssemblies.Add(tipo.Assembly.Location);
            cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
     
            cp.GenerateExecutable = false;
            cp.OutputAssembly = globais["UTGeneratorVisualizerdll"].ToString() + @"\UTGeneratorVisualizer.dll";
            cp.GenerateInMemory = false;

            string assemblyAtual = Assembly.GetExecutingAssembly().GetName().Name.ToString();
            string visualizador = LerEmbeddedResource(assemblyAtual, "Visualizador.cs").Replace("decimal", tipo.FullName);
            string referenciaXml = globais["SystemXmldll"].ToString().Replace(@"\\",@"\");
            string geradorTestes = LerEmbeddedResource(assemblyAtual, "GeradorTestes.cs").Replace("refxml", referenciaXml);

            CompilerResults cr = provider.CompileAssemblyFromSource(cp, visualizador, geradorTestes); ;

            if (cr.Errors.Count > 0)
            {
                foreach (CompilerError ce in cr.Errors)
                {
                    System.Windows.Forms.MessageBox.Show(ce.ErrorText);
                }
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Debugger visualizer was generated successfully! Path: " + cr.PathToAssembly);
            }
        }

        private static string LerEmbeddedResource(string assemblyAtual, string nomeEmbeddedResource)
        {
            Stream arquivo = Assembly.GetExecutingAssembly().GetManifestResourceStream(assemblyAtual + "." + nomeEmbeddedResource);
            StreamReader reader = new StreamReader(arquivo);
            string retorno = reader.ReadToEnd();
            reader.Close();
            arquivo.Close();
            return retorno;
        }
    }
}
